Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

PHP4 : Один из способов организации работы с БД через DBsimple (Maus)
Author Message
Maus
Модератор



Joined: 29 Jun 2003
Posts: 8151
Карма: 271
   поощрить/наказать

Location: пос. Омсукчан Магаданской области

PostPosted: Thu Oct 12, 2006 12:43 pm (написано за 24 минуты 17 секунд)
   Post subject: PHP4 : Один из способов организации работы с БД через DBsimple
Reply with quote

Приведённый ниже материал не является чем-то новым - это просто компиляция давно известных вещей. Аналогичный вывод я нашел на XPoint (xpoint.ru/forums/programming/theory_algorythms/thread/30229.xhtml) (там это придумали ещё полтора года назад), но лишь на этой неделе.
Для совсем элементарных скриптов этот способ использовать, конечно, нерационально.
Подход использует библиотеки DBSimple (dklab.ru/lib/DbSimple/) (1.x) и Debug_HackerConsole (dklab.ru/lib/Debug_HackerConsole/) . Предполагается, что пути ко всем необходимым скриптам есть в include_path
Итак:
Code (php): скопировать код в буфер обмена
<?php
class DBService
{
    /**
     * @var DbSimple_Mysql_Transaction экземпляр DBSimple
     */

    var $db;
    /**
     * @var string хост, на котором размещена СУБД
     */

    var $db_host = 'localhost';
    /**
     * @var string имя пользователя
     */

    var $db_user = 'test_db';
    /**
     * @var string пароль
     */

    var $db_password = 'test_pass';
    /**
     * @var string имя БД
     */

    var $db_db = 'test_db';
    /**
    * @static
    * @access public
    */

    function & getInstance()
    {
        static (www.php.net/static) $instance = null;

        if ((isset (www.php.net/isset) ($this)) && (get_class (www.php.net/get_class)($this) == __CLASS__))
            trigger_error (www.php.net/trigger_error)('Статический метод класса ' .
                             __CLASS__ . '::' . __FUNCTION__ . '() вызван ' .
                            'как не статический', E_USER_ERROR);

        if (is_null (www.php.net/is_null)($instance))
        {
            //дружно благодарим Андрея Сухачева (компания "Информ-Мобил")
            // за ценное замечание с использованием массива
            $instance = array (www.php.net/array) ();
            $instance[0] = & new DBService(null);
        }
        return $instance[0];
    }

    /**
    * @access private
    */

    function DBService($instance = "fake")
    {

        if (!is_null (www.php.net/is_null)($instance))
            trigger_error (www.php.net/trigger_error)('Нельзя использовать конструтор для создания ' .
                    'класса DBService. Используйте статический ' .
                    'метод getInstance ()', E_USER_ERROR);
        require_once ('DbSimple/DSN.php');

        $dsn = sprintf (www.php.net/sprintf)('mysql://%s:%s@%s/%s',
                        $this->db_user, $this->db_password, $this->db_host, $this->db_db);
       
        // Подключаемся к БД.
        $DATABASE = DbSimple_DSN::connect($dsn);
       
        // Устанавливаем обработчик ошибок.
        $DATABASE->set_error_handler(array (www.php.net/array)(&$this, '_databaseErrorHandler'));
        // Стартуем новую транзакцию.
        $this->db = $DATABASE->transaction();
        if (!$this->db) die (www.php.net/die)('Database problems');
        // подключаем логгер
        $this->db->database->setLogger(array (www.php.net/array)('DBService', '_Logger'));
        $this->test = rand (www.php.net/rand)();
    }

    /**
     * Код обработчика ошибок SQL.
     * @param string $message
     * @param string $info
     *
     */

    function _databaseErrorHandler($message, $info)
    {
        // Если использовалась @, ничего не делать.
        if (!error_reporting (www.php.net/error_reporting)()) return;
        // Выводим подробную информацию об ошибке. Причем в консоль или в никуда
        if (@$GLOBALS['Debug_HackerConsole_Main_LAST'])
        {
            call_user_func (www.php.net/call_user_func)(array (www.php.net/array)('Debug_HackerConsole_Main', 'out'),
                            'SQL Error: '.$message, 'sql_errors');
            call_user_func (www.php.net/call_user_func)(array (www.php.net/array)('Debug_HackerConsole_Main', 'out'),
                            $info, 'sql_errors');
        }
    }
   
    /**
     * логгер запросов
     *
     * @param DbSimple_Abstract_Database $db
     * @param string $sql скомпилированный sql-запрос
     */

    function _Logger($db, $sql)
    {
        // Находим контекст вызова этого запроса.
        $callers = $db->findLibraryCaller();
        $caller = $callers[0];
        $tip = 'at '.@$caller['file'].' line '.@$caller['line'];
        // Печатаем запрос в консоль или в никуда.
        if (@$GLOBALS['Debug_HackerConsole_Main_LAST'])
        {
            call_user_func (www.php.net/call_user_func)(array (www.php.net/array)('Debug_HackerConsole_Main', 'out'),
                            '/*'.$tip.'*/ ', 'sql');
            call_user_func (www.php.net/call_user_func)(array (www.php.net/array)('Debug_HackerConsole_Main', 'out'), $sql, 'sql');
        }
    }
   
    /**
     * Возвращает информацию по аккаунту
     *
     * Это пример функции. Предполагается, что обращений к аккаунтам много и
     * некоторые обращения могут быть повторными
     *
     * @return array данные по аккаунту.
     */

     function Login_get ($id)
    {
        static (www.php.net/static) $result = null;
        if (is_null (www.php.net/is_null)($result))
            $result$this->db->select(
                            'SELECT l.account_id AS ARRAY_KEY, l.* ' .
                            'FROM `login` l ');
        return (isset (www.php.net/isset)($result[$id])) ? $result[$id] : array (www.php.net/array)();
    }
}


?>
подключение и использование в каком-то скрипте:
Code (php): скопировать код в буфер обмена
</php
// .. всякие предварительные действия - вроде добавления каталога с библиотеками в include_path
$db =& DBService::getInstance();

$db->Login_get(2);
Преимущества
  1. DBSimple - удобная работа с запросами
  2. Debug_HackerConsole - удобный вывод отладочной информации (например, она может подключаться только для разработчиков и отсуствовать для обычных посетителей )
  3. паттерн Singleton - гарантирует, что у нас будет задействовано только 1 копия DBService (а значит, и 1 коннект к БД). Код, реализующий паттерн, взят с PHPClub.ru (phpclub.ru/faq/wakka.php?wakka=DesignPatterns/Singleton)
  4. Откуда DBService берёт информацию, несущественно - например, некторые методы могут работать не с базой, а с файлами.
  5. Собрание всех SQL-запросов в одном месте иногда позволяет увидеть более эффективный способ взаимодействия с БД (сократить число различных запросов)
Back to top
View user's profile Send private message
Антон Макаренко
Участник форума



Joined: 05 Feb 2004
Posts: 374
Карма: 37
   поощрить/наказать

Location: Киев

PostPosted: Fri Mar 28, 2008 4:15 pm (спустя 1 год 5 месяцев 16 дней 3 часа 32 минуты; написано за 1 минуту 32 секунды)
   Post subject:
Reply with quote

Решил поднять топик, освежив его упрощенным аналогом синглтона под php5
Code (php): скопировать код в буфер обмена
<?php
class Db_Single
{
    private static (www.php.net/static) $_singleton_instance;

    private function __construct()
    {
    }

    public static (www.php.net/static) function init($dsn = null)
    {
        if (isset (www.php.net/isset)(self::$_singleton_instance))
            return self::$_singleton_instance;
        self::$_singleton_instance = DbSimple_Generic::connect($dsn);
        return self::$_singleton_instance;
    }
}
Соответственно, в локальной области видимости доступ к объекту получаем таким способом:
Code (php): скопировать код в буфер обмена
$db = Db_Single::init();
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML